/**
 * @file Defs.h
 * @brief Data structures, constants, and macros internal to GDR
 *
 * @author Matt Stallmann @date 18 Dec 2001
 * $Id: Defs.h 10 2007-06-28 20:08:57Z mfms $
 */

/*
 *  Copyright (C) 2001 Matthias Stallmann.
 *  Contact: matt_stallmann@ncsu.edu
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program (file COPYING.txt); if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
 *  USA.
 */

#ifndef DEFS_H
#define DEFS_H

/* global constants */
#define ALL_ON  0xffffffff
#define ALL_OFF 0
#define GDR_CODE "^$)("         /**< 1st line in a data file */
#define PI_2   1.5707963        /**< pi / 2 */

/* Macros for access to X11 fields */
#define XC  xbutton.x
#define YC  xbutton.y
#define BUT xbutton.button
#define WIN xbutton.window

/* Masks for display characteristics */
#define EXP_MSK 0x1  /**< the label win exposed bit */
#define H_L_MSK 0x2  /**< the highlight bit */
#define DSP_MSK 0x4  /**< the display bit (is this item displayed or hidden?) */

/******** graph data structures **************/
/* nodes for linked lists of edges */
typedef struct head_node H_NODE; /**< head node */
typedef struct list_node L_NODE; /**< regular node */

/* indexed vertex node */
typedef struct ind_vx {
  int    my_id;                 /**< vertex identifier (not really needed) */
  int    my_x;                  /**< vertex X and Y co-ords resp.   */
  int    my_y;
  int    i_am_deleted;          /**< logical for vertex deletion */
  int    my_vx_display;            /**< display data - lsb - vlabel exposed if 1,
                                   vertex highlighted if 1 */
  Window my_vx_label_window;       /**< the vx label win */
  char   my_vx_label[LINE_LENGTH];       /**< the vx label string */
  int    my_vx_label_x;            /**< position of the vx label win */
  int    my_vx_label_y;
  H_NODE * my_adj_list;         /**< adjacency list for this vertex */
} I_VX_NODE;

/* macros for vertex structure access */
#define VID(vx)     vx_array[vx].my_id
#define XCORD(vx)   vx_array[vx].my_x
#define YCORD(vx)   vx_array[vx].my_y
#define DEL(vx)     vx_array[vx].i_am_deleted
#define VWIN(vx)    vx_array[vx].my_vx_label_window
#define VLX(vx)     vx_array[vx].my_vx_label_x
#define VLY(vx)     vx_array[vx].my_vx_label_y
#define VLABEL(vx)  vx_array[vx].my_vx_label
#define V_DB(vx)    vx_array[vx].my_vx_display
#define ADJ(vx)     vx_array[vx].my_adj_list
#define V_FIRST(vx) first_on_list( vx_array[vx].my_adj_list )

/* the record for an edge */
typedef struct ej_node {
  int    my_first_vertex;       /**< edge is (my_first_vertex,my_second_vertex) */
  int    my_second_vertex;
  int    my_display;            /**< edge display data:
                                   bit 0: label exposed iff 1,
                                   bit 1: edge highlighted iff 1
                                   bit 2: edge displayed iff 1 */
  int    my_knots[2][2];        /**< the positions for the knots */
  Window my_label_window;       /**< the label window   */
  int    my_label_x;            /**< the co-ordinates for the edge label */
  int    my_label_y;
  char   my_label[LINE_LENGTH];       /**< the label string */
} EJ_NODE;

/* macros to access information from a node pointer, which is how the
   'edge' type is defined */
#define LNK(pt)      next_on_list( pt )
#define NXT(pt)      next_on_list( pt )
#define EDG(pt)      get_edge_record( pt )
#define IS_VALID_EJ(pt) (pt != NULL_EDGE && get_edge_record( pt ) != NULL)
#define VX_1(pt)  get_edge_record( pt )->my_first_vertex
#define VX_2(pt)  get_edge_record( pt )->my_second_vertex
#define LWIN(pt)  get_edge_record( pt )->my_label_window
#define LX(pt)    get_edge_record( pt )->my_label_x
#define LY(pt)    get_edge_record( pt )->my_label_y
#define KN(pt,i,j) get_edge_record( pt )->my_knots[i][j]
#define LABEL(pt) get_edge_record( pt )->my_label
#define E_DB(pt)  get_edge_record( pt )->my_display

/** @file Defs.h
    CONVENTIONS: (some violations may continue to exist in legacy code)
     - macros are used for access only, not modification
     - modification of the graph structure takes place only in the
     following low-level procedures:
        init_structures     (gr.c)
        ins_ej_lst          (gr_tool.c)
        ins_lwin_lst        (gr_tool.c)
        create_lab_window   (gr_tool.c)
        read_in_gr          (gr_tool.c)
        clear_graph         (gr_tool.c)
        creat_ej_record     (gr_tool.c)
        are_edges_equal     (list.c)
        add_edge            (list.c)
        add_vertex          (list.c)
        delete_vertex       (list.c)
        delete_edge         (list.c)
*/ 

/*********************************************************************/

/* macros for navigation of the popup menu (and similar structures) */
/** y-coordinate of text baseline for i-th menu item */
#define MENU_TXT_BASE(i,height,padding) ((height+padding)*(i+1)-padding/2)
/** y-coordinate of top of "panel" for i-th menu item */
#define MENU_ITEM_TOP(i,height,padding) ((height+padding)*i+padding/2)
/** get menu item index from y-coordinate */
#define MENU_ITEM_FROM_Y(y,height,padding) (y/(height+padding))

/* constants used as indices into the 'help message list' */
#define HELP_CATEGORIES 3       /**< 3 categories of messages (panel, menu,
                                   other) */
#define PANEL_HELP 0
#define MENU_HELP  1
#define OTHER_HELP 2

#define MSG_PER_CATEGORY 10     /**< upper bound on number of messages per
                                   category */

      /* mouse buttons */
#define LEFT_BUTTON   1
#define MIDDLE_BUTTON 2
#define RIGHT_BUTTON  3

      /* panel Mnemonics */
#define PANEL_TOPICS  6         /**< number of panel topics */
#define CREATE_VERTEX 0
#define CREATE_EDGE   1
#define MOVE          2
#define DELETE        3
#define EDIT_LABEL    4
#define POPUP_MENU    5
#define IS_DIRECTED   6         /**< special panel position for
                                   directed/undirected indicator (not
                                   counted) */ 
      /* pop_up menu Mnemonics */
#define MENU_TOPICS   7         /**< number of pop_up menu topics */
#define SAVE          0
#define READ          1
#define REDRAW        2
#define INIT          3
#define CLEAR         4
#define RUN           5
#define QUIT          6
#define NULL_TOPIC   (-1)
      /* other help strings */
#define OTHER_TOPICS  5         /**< The number of extra help strings in GDR */
#define GENERAL       0
#define LOOP_PROMPT   1
#define TOO_MANY_VERTICES 2
#define SELECT_VERTEX 3
#define NO_HELP       4

/* miscellaneous macros (probably should be utility functions instead) */
#define DRAW_STR(w,x,y,str) XDrawString(disp,w,rubber_gc,x,y,str,strlen(str))
#define DIST(x1,y1,x2,y2)  sqrt((double)(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))

#endif
/* end of Defs.h */

/*  [Last modified: 2007 06 28 at 19:12:09 GMT] */
